package com.csx.governance.traffic.adm.controller;

import com.csx.governance.traffic.adm.model.bo.SwimLaneDefinitionBO;
import com.csx.governance.traffic.adm.model.bo.SwimLaneRouteRuleBO;
import com.csx.governance.traffic.adm.model.common.Result;
import com.csx.governance.traffic.adm.model.dto.ImportResultDTO;
import com.csx.governance.traffic.adm.model.dto.SwimLaneDefinitionDTO;
import com.csx.governance.traffic.adm.model.dto.SwimLaneRouteRuleDTO;
import com.csx.governance.traffic.adm.model.vo.ImportResultVO;
import com.csx.governance.traffic.adm.model.vo.SwimLaneDefinitionVO;
import com.csx.governance.traffic.adm.model.vo.SwimLaneRouteRuleVO;
import com.csx.governance.traffic.adm.service.SwimLaneRouteService;
import com.csx.governance.traffic.adm.util.ModelConvertUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * @author cuisongxu
 * @date 2023/4/23 15:26
 */
@Tag(name = "泳道路由控制器")
@RequestMapping("/swimlane-route")
@RestController
@AllArgsConstructor
public class SwimLaneRouteController {

    private final SwimLaneRouteService swimLaneRouteService;

    /**
     * 获取泳道路由规则列表
     * @param serviceName 服务名(可以为空，空的情况下表示获取所有规则)
     * @param pageNum 第几页
     * @param pageSize 每页大小
     * @return 泳道路由规则列表
     */
    @Operation(summary = "获取泳道路由规则列表")
    @GetMapping("/rules")
    public Result<List<SwimLaneRouteRuleVO>> getSwimLaneRouteRules(@RequestParam(name = "serviceName", required = false) @Parameter(description = "期望获取泳道规则的服务名") String serviceName,
                                                           @RequestParam(name = "pageNum", required = false, defaultValue = "1") @Parameter(description = "第几页") Integer pageNum,
                                                           @RequestParam(name = "pageSize", required = false, defaultValue = "10") @Parameter(description = "每页大小") Integer pageSize) {
        List<SwimLaneRouteRuleDTO> swimLaneRouteRules = swimLaneRouteService.getSwimLaneRouteRules(serviceName, pageNum, pageSize);
        List<SwimLaneRouteRuleVO> res = ModelConvertUtil.convert(swimLaneRouteRules, SwimLaneRouteRuleVO.class);
        return Result.success(res);
    }

    /**
     * 新增泳道路由规则
     * @param swimLaneRouteRuleDTO 泳道路由规则传输实体
     */
    @Operation(summary = "新增泳道路由规则")
    @PostMapping("/add-rule")
    public Result<Void> addSwimLaneRouteRule(@RequestBody @Parameter(description = "泳道路由规则传输实体") SwimLaneRouteRuleDTO swimLaneRouteRuleDTO) {
        SwimLaneRouteRuleBO swimLaneRouteRuleBO = ModelConvertUtil.convert(swimLaneRouteRuleDTO, SwimLaneRouteRuleBO.class);
        swimLaneRouteService.addSwimLaneRouteRule(swimLaneRouteRuleBO);
        return Result.success();
    }

    /**
     *
     * 修改泳道路由规则
     * @param swimLaneRouteRuleDTO 泳道路由规则传输实体
     */
    @Operation(summary = "修改泳道路由规则")
    @PostMapping("/update-rule")
    public Result<Void> updateSwimLaneRouteRule(@RequestBody @Parameter(description = "泳道路由规则传输实体") SwimLaneRouteRuleDTO swimLaneRouteRuleDTO) {
        SwimLaneRouteRuleBO swimLaneRouteRuleBO = ModelConvertUtil.convert(swimLaneRouteRuleDTO, SwimLaneRouteRuleBO.class);
        swimLaneRouteService.updateSwimLaneRouteRule(swimLaneRouteRuleBO);
        return Result.success();
    }

    /**
     * 删除泳道路由规则
     * @param serviceNames 需要删除规则的服务名列表
     */
    @Operation(summary = "删除泳道路由规则")
    @PostMapping("/delete-rules")
    public Result<Void> deleteSwimLaneRouteRules(@RequestBody @Parameter(description = "需要删除规则的服务名列表") List<String> serviceNames) {
        swimLaneRouteService.deleteSwimLaneRouteRules(serviceNames);
        return Result.success();
    }

    /**
     * 导出泳道路由规则。特别注意: 导出的内容中除了泳道规则，还要包含规则中对应的泳道定义
     * @param serviceNames 需要导出的泳道路由规则的服务名列表
     * @param response 响应对象，将导出的内容写入到响应对象中
     */
    @Operation(summary = "导出泳道路由规则")
    @PostMapping("/export-rules")
    public void exportSwimLaneRouteRules(@RequestBody @Parameter(description = "需要导出规则的服务名列表") List<String> serviceNames, HttpServletResponse response) {
        swimLaneRouteService.exportSwimLaneRouteRules(serviceNames, response);
    }

    /**
     * 导入泳道路由规则
     * @param file 导入的文件
     * @param repeatStrategyCode 重复处理策略码: 0: 跳过; 1 覆盖; 2 终止
     * @return 导入结果
     */
    @Operation(summary = "导入泳道路由规则")
    @PostMapping("/import-rules")
    public Result<ImportResultVO<ImportResultVO.SwimLaneRouteRuleKVO>> importSwimLaneRouteRules(@RequestParam("file") @Parameter(description = "文件对象") MultipartFile file,
                                                                                                @RequestParam("repeatStrategyCode") @Parameter(description = "重复策略码 0: 跳过; 1 覆盖; 2 终止") Integer repeatStrategyCode) throws IOException {
        ImportResultDTO<ImportResultDTO.SwimLaneRouteRuleKDTO> importResultDTO = swimLaneRouteService.importSwimLaneRouteRules(new String(file.getBytes()), repeatStrategyCode);
        ImportResultVO<ImportResultVO.SwimLaneRouteRuleKVO> importResultVO = ModelConvertUtil.convert(importResultDTO, ImportResultVO.class);
        return Result.success(importResultVO);
    }

    /**
     * 获取泳道定义列表
     * @param swimLaneId 泳道ID(可以为空，空的情况下表示获取所有泳道的泳道定义)
     * @param pageNum 第几页
     * @param pageSize 每页大小
     * @return 泳道定义列表
     */
    @Operation(summary = "获取泳道定义列表")
    @PostMapping("/definitions")
    public Result<List<SwimLaneDefinitionVO>> getSwimLaneDefinitions(@RequestParam(name = "swimLaneId", required = false) @Parameter(description = "预期获取定义的泳道ID") String swimLaneId,
                                                                     @RequestParam(name = "pageNum", required = false, defaultValue = "1") @Parameter(description = "第几页") Integer pageNum,
                                                                     @RequestParam(name = "pageSize", required = false, defaultValue = "10") @Parameter(description = "每页大小") Integer pageSize) {
        List<SwimLaneDefinitionDTO> swimLaneDefinitions = swimLaneRouteService.getSwimLaneDefinitions(swimLaneId, pageNum, pageSize);
        List<SwimLaneDefinitionVO> res = ModelConvertUtil.convert(swimLaneDefinitions, SwimLaneDefinitionVO.class);
        return Result.success(res);
    }

    /**
     * 新增泳道定义
     * @param swimLaneDefinitionDTO 泳道定义传输实体
     */
    @Operation(summary = "新增泳道定义")
    @PostMapping("/add-definition")
    public Result<Void> addSwimLaneDefinition(@RequestBody @Parameter(description = "泳道定义传输实体") SwimLaneDefinitionDTO swimLaneDefinitionDTO) {
        SwimLaneDefinitionBO swimLaneDefinitionBO = ModelConvertUtil.convert(swimLaneDefinitionDTO, SwimLaneDefinitionBO.class);
        swimLaneRouteService.addSwimLaneDefinition(swimLaneDefinitionBO);
        return Result.success();

    }

    /**
     * 修改泳道定义
     * @param swimLaneDefinitionDTO 泳道定义传输实体
     */
    @Operation(summary = "泳道定义传输实体")
    @PostMapping("/update-definition")
    public Result<Void> updateSwimLaneDefinition(@RequestBody @Parameter(description = "泳道定义传输实体") SwimLaneDefinitionDTO swimLaneDefinitionDTO) {
        SwimLaneDefinitionBO swimLaneDefinitionBO = ModelConvertUtil.convert(swimLaneDefinitionDTO, SwimLaneDefinitionBO.class);
        swimLaneRouteService.updateSwimLaneDefinition(swimLaneDefinitionBO);
        return Result.success();
    }

    /**
     * 删除泳道定义
     * @param swimLaneIds 要删除的泳道定义ID列表
     */
    @Operation(summary = "删除泳道定义")
    @PostMapping("/delete-definitions")
    public Result<Void> deleteSwimLaneDefinitions(@RequestBody @Parameter(description = "预期删除的泳道定义的泳道ID列表") List<String> swimLaneIds) {
        swimLaneRouteService.deleteSwimLaneDefinitions(swimLaneIds);
        return Result.success();
    }

}
